package handlers

import (
	"generalhandler/conf"
	"generalhandler/utils"
	"github.com/bitly/go-simplejson"
	"time"
)

type PortMapHandler struct {
}

func (pmh *PortMapHandler) Handle(bytesMsg []byte, log Logger, pub Publisher) error {
	start := time.Now().Unix()
	msg, err := simplejson.NewJson(bytesMsg)
	if nil != err {
		log.Warn("failed to NewJson %s, cuz %s", string(bytesMsg), err.Error())
		return nil
	}
	strDomain, err := msg.Get("domain").String()
	if nil != err {
		log.Warn("found no domain in %s", string(bytesMsg))
		return nil
	}
	strTkId, err := msg.Get("tkid").String()
	if nil != err {
		log.Warn("found no tkid in %s", string(bytesMsg))
		return nil
	}
	userId, err := msg.Get("userid").String()
	if nil != err {
		log.Warn("found no -userid in %v", string(bytesMsg))
		return nil
	}
	strSubDomain, err := msg.Get("subdomain").String()
	if nil != err {
		log.Warn("found no subdomain in %s", string(bytesMsg))
		return nil
	}

	strIgnore, _ := msg.Get("ignore").String()
	var ignoreMap map[string]interface{}
	ignoreMap = make(map[string]interface{})
	utils.StringToMap(strIgnore, ignoreMap)

	var iflist []interface{}
	list, err := msg.Get("ports").Array()
	if nil != err {
		item, err := msg.Get("ports").Map()
		if nil != err {
			log.Error("error %s in %v", err.Error(), msg.Get("ports"))
			return nil
		}
		iflist = append(iflist, item)
	} else {
		iflist = append(iflist, list...)
	}
	tmp := simplejson.New()
	tmp.Set("ports", iflist)
	newPorts := tmp.Get("ports")
	for i := 0; i < len(iflist); i++ {
		port := newPorts.GetIndex(i)
		strSvrState, err := port.Get("state").Get("-state").String()
		if nil != err {
			log.Warn("found no -state in %v", port)
			continue
		}
		if "open" != strSvrState {
			log.Info("port -state %s in %v", strSvrState, port)
			continue
		}
		strPortId, err := port.Get("-portid").String()
		if nil != err {
			log.Warn("found no -portid in %v", port)
			continue
		}
		strSvrName, err := port.Get("service").Get("-name").String()
		if nil != err {
			log.Warn("found no -name in %v", port)
			continue
		}

		handlers, ok := conf.PortMapInstance().Map[strSvrName]
		if !ok {
			log.Info("no need to handle %s service ", strSvrName)
			continue
		}

		new := simplejson.New()
		new.Set("domain", strDomain)
		new.Set("subdomain", strSubDomain)
		new.Set("tkid", strTkId)
		new.Set("userid", userId)
		new.Set("port", strPortId)
		new.Set("start", start)
		new.Set("end", time.Now().Unix())
		prefix, ok := conf.PortMapInstance().Prefix[strSvrName]
		if ok {
			new.Set("prefix", prefix)
		}
		bytesNew, err := new.MarshalJSON()
		if nil != err {
			log.Error("failed to marshal result %s, cuz %s", new, err.Error())
			continue
		}

		for _, handle := range handlers {
			if _, ok := ignoreMap[handle]; ok {
				continue
			}
			pub.PublishMessage(handle, bytesNew)
		}
	}

	return nil
}
